
/* This do-file replicates the results in the paper. 
	It requires the following user-written packages: frmttable, rdrobust, 
	rddensity, estout, qreg2
	Type findit [package name] and follow prompts to install them. */
	
frmttable, clear
clear *

* load programs for exporting results
do _programs.do

* covariate groups
global covars1 ccode2-ccode11 year_2-year_15
global covars2 $covars1 threshold_2-threshold_33


/** Table C1 **/

use data-main, clear
preserve
collapse year, by(country citycode)
drop year
gen count = 1
collapse (sum) count, by(country)
ren count muni
mkmat muni, mat(muni)
restore, preserve
* number of obs (of CRI)
keep if cri ~= .
gen count = 1
collapse (sum) count, by(country)
ren count contr
mkmat contr, mat(contr)
restore
* year span
collapse (min) miny=year (max) maxy=year, by(country)
mkmat miny maxy, mat(years)
mat all = years, contr, muni
frmttable, statmat(all) substat(0) sdec(0) sfmt(g,g,gc,gc) ///
	rtitles("Austria" \ "Belgium" \ "France" \ "Hungary" \ "Italy" \ ///
			"Lithuania" \ "Portugal" \ "Romania" \ "Slovakia" \ "Slovenia" \ ///
			"Spain")
		

/** Table C2 **/

use data-main, clear
estpost sum no_cft corr_proc corr_subm corr_decp corr_singleb corr_buyer_concentration cri cri2
foreach x in count mean sd min max {
	mat `x' = e(`x')'
}
mat sum = count, mean, sd, min, max
mat list sum
frmttable, clear
frmttable, statmat(sum) substat(0) sdec(0,2,2,2,2) ///
	rtitles("No call for tender" \ "Non-open procedure" \ "Short bid submission period" \ ///
			"Short bidder decision period" \ "Single bidder" \ "Supplier spending concentration" \ ///
			"CRI" \ "CRI (listwise)")


/** Figure C1 **/

use data-main, clear
bys citycode year: egen no = count(cri)
bys citycode: egen min = min(no)
gen min30 = (min >= 30) & min ~= .
collapse cri if min30 == 1, by(countrycode citycode year)
graph box cri, over(countrycode, sort(1)) noout ///
		ytitle("Procurement Corruption Risk", size(small)) ///
	graphregion(margin(0 0 0 0)) aspectratio(1) ///
	xsize(4.15) ysize(4.15) note("")


/** Figure C2 **/

use data-main, clear
collapse salary_ppp, by(countrycode citycode year)
sum salary_ppp, d
graph box salary_ppp, over(countrycode, sort(1)) noout ///
	ytitle("Mayor's monthly salary ({c 0128} PPP)", size(small)) ///
	graphregion(margin(0 0 0 0)) aspectratio(1) ///
	xsize(4.15) ysize(4.15) note("")


/** Figure C3 **/

use data-main, clear
collapse margin uniques, by(citycode year salary_group)
rddensity margin if uniques == 1 & margin < 1, c(0) plot ///
	plotl_estype(none) plotl_citype(none) ///
	plotr_estype(none) plotr_citype(none) ///
	hist_range(-.25 .25) hist_n(25 25) ///
	graph_opt(title("") legend(off) xline(0, lpattern(shortdash) lcolor(black)) ///
	xtitle("Distance to the closest population-based unique salary threshold (inhabitants)") ///
	ytitle("Density"))


/** Table C3 **/

* lagged outcomes
use data-main, clear
keep if year < 2012
gen bid_digiwhist_price_ppp = bid_digiwhist_price/ppp_conversion_factor
foreach x in cri2 cri no_cft corr_proc corr_subm corr_decp ///
	corr_singleb corr_buyer_concentration bid_digiwhist_price_ppp {
	gen l_`x' = `x'
}
replace l_bid_digiwhist_price_ppp = asinh(l_bid_digiwhist_price_ppp) ///
	if l_bid_digiwhist_price_ppp > 10
replace year = year + 6
collapse l_*, by(country year citycode salary_group)
tempfile lt
save `lt', replace
use data-main, clear
drop if year < 2012
drop if year > 2017
collapse margin uniques ccode* year_* threshold_2-threshold_33, ///
	by(country year citycode salary_group)
merge 1:1 country year citycode salary_group using `lt'
drop _m
frmttable, clear
forval i = 1/12 {
	matrix b`i' = J(1,5,.)
	}
local j = 1
qui {
	foreach x in cri no_cft corr_proc corr_subm corr_decp ///
		corr_singleb corr_buyer_concentration bid_digiwhist_price_ppp {
			rdrobust l_`x' margin if uniques == 1 & margin < 1, ///
				covs($covars1) vce(cluster citycode) all
			storeb `j'
			loc j = `j' + 1
	}
}
* other variables
use data-city-characteristics, clear
loc j = 9
qui {
foreach x in employment foreigners average_monthly ///
	population_density {
		rdrobust `x' margin if uniques == 1 & margin < 1, ///
			covs($covars1) vce(cluster citycode) all
		storeb `j'
		loc j = `j' + 1
	}
}
mat t = b1
forval i = 2/12 {
	mat t = t \ b`i'
}
frmttable, statmat(t) sdec(3,3,3,3,0,0) ///
	rtitles("Corruption risk index (lagged)" \ ///
		"No call for tender (lagged)" \ ///
		"Non-open procedure (lagged)" \ ///
		"Short bid submission period (lagged)" \ ///
		"Short bidder decision period (lagged)" \ ///
		"Single bidder (lagged)" \ ///
		"Supplier concentration (lagged)" \ ///
		"Average bid price (lagged)" \ ///
		"Employment rate (% of total population)" \ ///
		"Foreign residents (% of total population)" \ ///
		"Average monthly income (euros)" \ ///
		"Population density (inhabitants per km2)")


/** Table C4 **/

frmttable, clear
forval i = 1/3 {
	matrix r`i' = J(1,3,.)
	}
matrix s = J(2,3,.)
use data-main, clear
qui {
	rdrobust cri2 margin if uniques == 1 & margin < 1 & (margin < -.0025 | margin > .0025), ///
		covs($covars1) vce(cluster citycode) all
	stores 1
	rdrobust cri2 margin if uniques == 1 & margin < 1 & (margin < -.005 | margin > .005), ///
		covs($covars1) vce(cluster citycode) all
	stores 2
	rdrobust cri2 margin if uniques == 1 & margin < 1 & (margin < -.01 | margin > .01), ///
		covs($covars1) vce(cluster citycode) all
	stores 3
}
cmb_tbl 3


/** Figure C4 **/

use data-main, clear
qui rdrobust cri2 margin if uniques == 1 & margin < 1, ///
	covs($covars1) vce(cluster citycode) all
loc oh = e(h_l)
loc ohl = e(h_l)/2
loc ohd = e(h_l)*2
loc obs = abs(round(((`ohl'-`ohd')/.01),1)) + 3
mat e = J(`obs',3,.)
loc oht = `oh' + .003
loc j = 1
forval i = .05(.01).22 {
	di `i'	
	qui rdrobust cri2 margin if uniques == 1 & margin < 1, ///
		covs($covars1) vce(cluster citycode) all h(`i' `i')
	mat e[`j',1] = e(tau_bc)
	mat e[`j',2] = e(ci_l_rb)
	mat e[`j',3] = e(ci_r_rb)
	loc j = `j' + 1
}
clear
svmat e
gen n = .
loc j = 1
forval i = .05(.01).22 {
	replace n = `i' in `j'
	loc j = `j' + 1
}
twoway (rarea e2 e3 n, color(gs8%30)) ///
	(line e1 n, lpattern(solid) lcolor(black)), ///
	legend(off) xtitle("Bandwidth size", size(small)) ///
	ytitle("RD estimate", size(small)) ///
	yscale(range(-.2(.05).1)) ylabel(-.2 -.15 -.1 -.05 0 .05 .1) ///
	yline(0, lpattern(dash) lcolor(black) lwidth(vthin)) ///
	xline(`oh', lpattern(solid) lcolor(red) lwidth(vthin)) ///
	text(.05 `oht' "Optimal bandwidth", size(vsmall) ///
		orientation(vertical) color(red)) ///
	xlabel(#7) graphregion(margin(0 0 0 0)) aspect(1)

	
/** Table C5 **/

frmttable, clear
forval i = 1/2 {
	matrix r`i' = J(1,3,.)
	}
matrix s = J(2,3,.)
use data-main, clear
qui {
	rdrobust cri2 margin if unique == 1 & margin < 1, ///
		covs($covars1) vce(cluster citycode) all 
	stores 1
	rdrobust cri2 margin if non_unique == 1 & margin < 1, ///
		covs($covars2) vce(cluster citycode) all
	stores 2
}
cmb_tbl 2


/** Table C6 **/

frmttable, clear
forval i = 1/3 {
	matrix r`i' = J(1,3,.)
	}
matrix s = J(2,3,.)
use data-main, clear
gen bid_digiwhist_price_ppp = bid_digiwhist_price/ppp_conversion_factor
gen l_bid_digiwhist_price_ppp = asinh(bid_digiwhist_price_ppp) ///
	if bid_digiwhist_price_ppp > 10 & bid_digiwhist_price_ppp ~= .
qui {
	rdrobust l_bid_digiwhist_price_ppp margin if uniques == 1 & margin < 1, ///
		covs($covars1) vce(cluster citycode) all
	stores 1
}
gen one_b = 1 if bid_digiwhist_price_ppp ~= .
collapse (sum) bid_digiwhist_price_ppp one_b (mean) margin uniques ///
	ccode* year_* threshold_*, by(country citycode year)
gen l_bid_digiwhist_price_ppp = asinh(bid_digiwhist_price_ppp) ///
	if bid_digiwhist_price_ppp > 10 & bid_digiwhist_price_ppp ~= .
qui {
	rdrobust one_b margin if uniques == 1 & margin < 1, ///
		covs($covars1) vce(cluster citycode) all
	stores 2
	rdrobust l_bid_digiwhist_price_ppp margin if uniques == 1 & margin < 1, ///
		covs($covars1) vce(cluster citycode) all 
	stores 3
}
cmb_tbl 3


/** Table C7 **/

frmttable, clear
forval i = 1/2 {
	matrix r`i' = J(1,3,.)
	}
matrix s = J(2,2,.)

use data-main, clear
collapse (p50) salary_jump_percent, by(country citycode year)
collapse (p50) salary_jump_percent, by(country year)
collapse (p50) salary_jump_percent, by(country)
ren salary medjump
tempfile c
save `c', replace
use data-main, clear
merge m:1 country using `c'
drop _m
gen tile = (salary_jump_percent > medjump)
qui {
	rdrobust cri2 margin if non_uniques == 1 & margin < 1 & tile == 0, ///
		covs($covars2) vce(cluster citycode) all
	stores 1
	rdrobust cri2 margin if non_uniques == 1 & margin < 1 & tile == 1, ///
		covs($covars2) vce(cluster citycode) all
	stores 2	
}
cmb_tbl 2

	
/** Table C8 **/

frmttable, clear
forval i = 1/2 {
	matrix r`i' = J(1,3,.)
	}
matrix s = J(2,2,.)

use data-main, clear
collapse (p50) corruptionp, by(country citycode year)
collapse (p50) corruptionp, by(country year)
collapse (p50) corruptionp, by(country)
ren corruptionp corrp
tempfile c
save `c', replace
use data-main, clear
merge m:1 country using `c'
drop _m
gen tile = (corruptionp >= corrp)
qui {
	rdrobust cri2 margin if non_uniques == 1 & margin < 1 & tile == 1, ///
		covs($covars2) vce(cluster citycode) all
	stores 1
	rdrobust cri2 margin if non_uniques == 1 & margin < 1 & tile == 0, ///
		covs($covars2) vce(cluster citycode) all
	stores 2
}
cmb_tbl 2


/** Table C9 **/

frmttable, clear
forval i = 1/6 {
	matrix r`i' = J(1,3,.)
	}
matrix s = J(2,6,.)

use data-main, clear
global corrvars no_cft corr_proc corr_subm corr_decp corr_singleb corr_buyer_concentration
loc j = 1
qui {
	foreach y in $corrvars {
		rdrobust `y' margin if uniques == 1 & cri2 ~= . & margin < 2, ///
			covs($covars1) vce(cluster citycode) all
		stores `j'
		loc j = `j' + 1
	}	
}
cmb_tbl 6


/** Table C10 **/

forval i = 1/6 {
	matrix r`i' = J(1,3,.)
}
matrix s = J(2,6,.)

use data-main, clear
foreach x in bid_price lot_estimatedprice tender_finalprice tender_estimatedprice {
	gen `x'_ppp = `x'/ppp_conversion_factor
}
bys persistent_id: egen nr_lots = count(persistent_id)
gen estimated_price_ppp = lot_estimatedprice_ppp
replace estimated_price_ppp = tender_estimatedprice_ppp if nr_lots == 1 & lot_estimatedprice_ppp == .
gen relp = bid_price_ppp/estimated_price_ppp
replace relp = . if relp > 4 & relp ~= .
gen keep_relp = (country == "Hungary" | country == "Italy" | country == "Slovakia" ///
	| country == "Romania" | country == "Spain")
qui {
	rdrobust relp margin if uniques == 1 & margin < 1 & keep_relp == 1, ///
		covs($covars1) vce(cluster citycode) all
	stores 1
}
loc h = e(h_l)
loc j = 2
gen treat = (margin > 0) if margin ~= .
foreach x in 10 25 50 75 90 {
	di as error `x'
	qui qreg2 relp treat##c.margin##c.margin $covars1 ///
		if uniques == 1 & margin < 1 & keep_relp == 1 & margin > -`h' & margin < `h', ///
		quantile(`x') cluster(citycode)
	mat r`j'[1,1] = _b[1.treat]
	mat r`j'[1,2] = _se[1.treat]
	mat r`j'[1,3] = (1-normal(abs(_b[1.treat]/_se[1.treat])))*2
	mat s[1,`j'] = `h'
	mat s[2,`j'] = e(N)
	loc j = `j' + 1
}
cmb_tbl 6


/** Figure C6 **/

use data-romania, clear
* panel (a)
gen margin_t = margint if year >= 2018
replace margin_t = marginr if year < 2018
rddensity margin_t, c(0) plot hist_n(20 20) ///
	plotl_estype(none) plotl_citype(none) ///
	plotr_estype(none) plotr_citype(none) ///
	graph_opt(title("") legend(off) xline(0, lpattern(shortdash) lcolor(black)) ///
	graphregion(margin(0 0 0 0)) aspectratio(1) ///
	xsize(4.15) ysize(4.15) ///
	xtitle("Distance to the closest population-based salary threshold (%)", size(small)) ///
	ytitle("Density", size(small)))
* panel (b)
rddensity marginc, c(0) plot ///
	plotl_estype(none) plotl_citype(none) ///
	plotr_estype(none) plotr_citype(none) ///
	graph_opt(title("") legend(off) xline(0, lpattern(shortdash) lcolor(black)) ///
	graphregion(margin(0 0 0 0)) aspectratio(1) ///
	xsize(4.15) ysize(4.15) ///
	xtitle("Distance to the closest population-based salary threshold (%)", size(small)) ///
	ytitle("Density", size(small)))


/** Tables C11 and C12 **/

use data-romania, clear
gen margin_t = margint if year >= 2018
replace margin_t = marginr if year < 2018
replace foreign = foreign*100
replace unemp = 1-unemp
* Table C11
frmttable, clear
forval i = 1/14 {
	matrix b`i' = J(1,5,.)
	}
loc j = 1
qui {
	foreach x in l_crinew l_corr_proc ///
		l_corr_singleb l_bid_digiwhist_price ///
		unemp foreign edu_prim edu_sec ///
		hospital nurse pharma area_total area_agri ///
		pop_density {
			di "`x'"
			rdrobust `x' margin_t, covs(oras muni) ///
				vce(cluster citycode) all
			storeb `j'
			loc j = `j' + 1
	}
}
mat t = b1
forval i = 2/14 {
	mat t = t \ b`i'
}
frmttable, statmat(t) sdec(3,3,3,3,0,0) ///
	rtitles("Corruption risk index (lagged)" \ ///
		"Non-open procedure (lagged)" \ ///
		"Single bidder (lagged)" \ ///
		"Average bid price (lagged)" \ ///
		"Employment rate (percent of total population)" \ ///
		"Foreign residents (percent of total population)" \ ///
		"Primary school enrollment (% of total population)" \ ///
		"Secondary school enrollment (% of total population)" \ ///
		"Hospitals (per 1,000 inhabitants)" \ ///
		"Nursing homes (per 1,000 inhabitants)" \ ///
		"Pharmacies (per 1,000 inhabitants)" \ ///
		"Total area (km2)" \ ///
		"Total agricultural area (km2)" \ ///
		"Population density (inhabitants per km2)") 
* Table C12
frmttable, clear
forval i = 1/14 {
	matrix b`i' = J(1,5,.)
	}
loc j = 1
qui {
	foreach x in l_crinew l_corr_proc ///
		l_corr_singleb l_bid_digiwhist_price ///
		unemp foreign edu_prim edu_sec ///
		hospital nurse pharma area_total area_agri ///
		pop_density {
			di "`x'"
			rdrobust `x' marginc, covs(oras muni) ///
				vce(cluster citycode) all
			storeb `j'
			loc j = `j' + 1
	}
}
mat t = b1
forval i = 2/14 {
	mat t = t \ b`i'
}
frmttable, statmat(t) sdec(3,3,3,3,0,0) ///
	rtitles("Corruption risk index (lagged)" \ ///
		"Non-open procedure (lagged)" \ ///
		"Single bidder (lagged)" \ ///
		"Average bid price (lagged)" \ ///
		"Employment rate (percent of total population)" \ ///
		"Foreign residents (percent of total population)" \ ///
		"Primary school enrollment (% of total population)" \ ///
		"Secondary school enrollment (% of total population)" \ ///
		"Hospitals (per 1,000 inhabitants)" \ ///
		"Nursing homes (per 1,000 inhabitants)" \ ///
		"Pharmacies (per 1,000 inhabitants)" \ ///
		"Total area (km2)" \ ///
		"Total agricultural area (km2)" \ ///
		"Population density (inhabitants per km2)")


/** Figure C7 **/
	
use data-main, clear
keep if country == "Romania"
egen crinew = rowmean(corr_proc corr_singleb)
drop threshold_*
preserve
* pre-2018 period for localities where new thresholds introduced in 2018
gen p1 = (city_pop > 3000 & city_pop < 7000) if city_pop ~= . & comune == 1
gen p2 = (city_pop > 7000 & city_pop < 15000) if city_pop ~= . & comune == 1
gen p3 = (city_pop > 15000) if city_pop ~= . & comune == 1
gen p4 = (city_pop > 10000 & city_pop < 30000) & city_pop ~= . & oras == 1
gen p5 = (city_pop > 10000 & city_pop < 30000) & city_pop ~= . & muni == 1
gen p6 = (city_pop > 50000 & city_pop < 150000) & city_pop ~= . & muni == 1
gen margint = (city_pop-5000)/5000 if p1 == 1
replace margint = (city_pop-10000)/10000 if p2 == 1
replace margint = (city_pop-20000)/20000 if p3 == 1
replace margint = (city_pop-20000)/20000 if p4 == 1
replace margint = (city_pop-20000)/20000 if p5 == 1
replace margint = (city_pop-100000)/100000 if p6 == 1
keep if p1 == 1 | p2 == 1 | p3 == 1 | p4 == 1 | p5 == 1 | p6 == 1
gen treat = (year >= 2018)
bys year: egen crinew_t = mean(crinew) if treat == 0
bys year: egen crinew_tb = mean(crinew) if treat == 0 & margint <= .116
collapse crinew_t crinew_tb if treat == 0, by(year)
tempfile cpt
save `cpt', replace
* control group
restore
gen c1 = (city_pop < 6000) if city_pop ~= . & comune == 1
gen c2 = (city_pop < 30000) if city_pop ~= . & oras == 1
gen c3 = (city_pop > 25000 & city_pop < 75000) if city_pop ~= . ///
	& muni == 1
gen marginc = (city_pop-3000)/3000 if c1 == 1
replace marginc = (city_pop-10000)/10000 if c2 == 1
replace marginc = (city_pop-50000)/50000 if c3 == 1
keep if c1 == 1 | c2 == 1 | c3 == 1
gen treat = (year >= 2018)
bys year: egen crinew_c = mean(crinew) if treat == 0
bys year: egen crinew_cb = mean(crinew) if treat == 0 & marginc <= .134
collapse crinew_c crinew_cb if treat == 0, by(year)
merge 1:1 year using `cpt'
tsset year
* left panel
twoway (tsline crinew_c, lcolor(red) lpattern(dash) lwidth(medthick)) ///
	(tsline crinew_t, lcolor(black%50) lpattern(solid) lwidth(medthick)), ///
	legend(ring(0) pos(6) order(1 "Control group" 2 "Treatment group") row(1)) ///
	xlabel(#8) xtitle("") title({bf:All observations}) name(g1, replace)
* right panel
twoway (tsline crinew_cb, lcolor(red) lpattern(dash) lwidth(medthick)) ///
	(tsline crinew_tb, lcolor(black%50) lpattern(solid) lwidth(medthick)), ///
	legend(off) xlabel(#8) xtitle("") ///
	title({bf:Observations within optimal bandwidth}) name(g2, replace)
gr combine g1 g2, xcommon ycommon rows(1) ///
	l1("Corruption procurement risk", size(small))
	
	
/** Table C13 **/

frmttable, clear
forval i = 1/2 {
	matrix r`i' = J(1,3,.)
	}
matrix s = J(2,2,.)

use data-main, clear
replace non_uniques = 1 if threshold == 30001 & country == "Italy"
replace non_uniques = 1 if threshold == 500001 & country == "Italy"
replace non_uniques = 1 if threshold == 5001 & country == "Italy"
qui {
	rdrobust cri3 margin if non_uniques == 1 & margin < 1 & term_limit == 0 ///
		& multiterm == 1, covs($covars2) vce(cluster citycode) all 
	stores 1
	rdrobust cri3 margin if non_uniques == 1 & margin < 1 & term_limit == 1 ///
		& multiterm == 1, covs($covars2) vce(cluster citycode) all
	stores 2	
}
cmb_tbl 2


/** Table C14 **/
	
frmttable, clear
forval i = 1/4 {
	matrix r`i' = J(1,3,.)
	}
matrix s = J(2,4,.)

use data-main, clear
cap drop indirect
gen indirect = 0
replace indirect = 1 if country == "Austria" & (state == "Niederösterreich" | state == "Steiermark")
replace indirect = 1 if country == "Belgium" & state ~= "Wallonia"
replace indirect = 1 if country == "France" | country == "Portugal" | country == "Spain"
replace indirect = 1 if country == "Lithuania" & year < 2015
replace indirect = 0 if country == "Spain" & city_pop <= 100
qui {
	rdrobust cri3 margin if non_uniques == 1 & margin < 1 & indirect == 0, ///
		covs(year_2-year_15 threshold_2-threshold_33) vce(cluster citycode) all 
	stores 1
	rdrobust cri3 margin if non_uniques == 1 & margin < 1 & indirect == 1, ///
		covs(year_2-year_15 threshold_2-threshold_33) vce(cluster citycode) all
	stores 2
	rdrobust cri3 margin if non_uniques == 1 & indirect == 0 & margin < 1 ///
		& (country == "Austria" | country == "Belgium"), ///
		covs($covars2) vce(cluster citycode) all
	stores 3
	rdrobust cri3 margin if non_uniques == 1 & indirect == 1 & margin < 1 ///
		& (country == "Austria" | country == "Belgium"), ///
		covs($covars2) vce(cluster citycode) all
	stores 4	
}
cmb_tbl 4

* end